package com.deparse.dpframe.utils;

import android.content.Context;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.loopj.android.http.SyncHttpClient;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by hsy on 2016/2/2.
 */
public class DPHttpUtil {
    public static final int TYPE_VOLLEY_ERROR = 0;
    public static final int TYPE_ASYNC_HTTP_CLIENT_ERROR = 1;

    private static final String requestTag = "requestTag";

    private static RequestQueue requestQueue = null;

    private static SyncHttpClient httpClient;

    static {
        httpClient = new SyncHttpClient();
    }

    public interface HttpCallback {
        void onSuccess(int what, String response);

        void onError(int what, int type, VolleyError error);
    }

    public static void init(Context applicationContext) {
        DPHttpUtil.requestQueue = Volley.newRequestQueue(applicationContext);
    }

    public static void cancelRequest() {
        if (null == DPHttpUtil.requestQueue) {
            try {
                throw new Exception("HttpUntil not inited");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
        requestQueue.cancelAll(requestTag);
    }

    public static void newRequest(final int what, final String url, final HttpCallback httpCallback, final int method, final Map<String, String> headers, final Map<String, String> params) {
        String tmp = "";
        tmp += ("what=" + what);
        tmp += ("url=" + url);
        tmp += ("httpCallback=" + (null == httpCallback ? "null" : httpCallback.toString()));
        tmp += ("method=" + method);
        tmp += ("headers=" + (null == headers ? "null" : headers.toString()));
        tmp += ("params=" + (null == params ? "null" : params.toString()));
        DPLogUtil.enter(tmp);
        if (null == DPHttpUtil.requestQueue) {
            try {
                throw new Exception("HttpUntil not inited");
            } catch (Exception e) {
                e.printStackTrace();
            }
            return;
        }
        StringRequest stringRequest = new StringRequest(method, url, new Response.Listener<String>() {
            @Override
            public void onResponse(String response) {
                if (null != httpCallback) {
                    httpCallback.onSuccess(what, response);
                }
            }
        }, new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                error.printStackTrace();
                if (null != httpCallback) {
                    httpCallback.onError(what, TYPE_VOLLEY_ERROR, error);
                }
            }
        }) {
            @Override
            public Map<String, String> getHeaders() throws AuthFailureError {
                if (null != headers) {
                    Map<String, String> p = new HashMap<>();
                    if (null != super.getHeaders() && 0 != super.getHeaders().size()) {
                        p.putAll(super.getHeaders());
                    }
                    p.putAll(headers);
                    return p;
                } else {
                    return super.getHeaders();
                }
            }

            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                if (null != params) {
                    Map<String, String> p = new HashMap<>();
                    if (null != super.getParams() && 0 != super.getParams().size()) {
                        p.putAll(super.getParams());
                    }
                    p.putAll(params);
                    return p;
                } else {
                    return super.getParams();
                }
            }
        };
        RetryPolicy policy = new DefaultRetryPolicy(30 * 1000, 5, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
        stringRequest.setRetryPolicy(policy);
        stringRequest.setTag(requestTag);
        DPHttpUtil.requestQueue.add(stringRequest);
//        DPHttpUtil.requestQueue.start();
    }

    public static void httpGet(final int what, final String url, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.GET, null, null);
    }

    public static void httpPost(final int what, final String url, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.POST, null, null);
    }

    public static void httpPut(final int what, final String url, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.PUT, null, null);
    }

    public static void httpDelete(final int what, final String url, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, null, null);
    }

    public static void httpGetWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.GET, headers, null);
    }

    public static void httpPostWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.POST, headers, null);
    }

    public static void httpPutWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.PUT, headers, null);
    }

    public static void httpDeleteWithHeaders(final int what, final String url, final Map<String, String> headers, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, headers, null);
    }

    public static void httpGetWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.GET, null, params);
    }

    public static void httpPostWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.POST, null, params);
    }

    public static void httpPutWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.PUT, null, params);
    }

    public static void httpDeleteWithParams(final int what, final String url, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, null, params);
    }

    public static void httpGetWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.GET, headers, params);
    }

    public static void httpPostWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.POST, headers, params);
    }

    public static void httpPutWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.PUT, headers, params);
    }

    public static void httpDeleteWithHeadersAndParams(final int what, final String url, final Map<String, String> headers, final Map<String, String> params, final HttpCallback httpCallback) {
        newRequest(what, url, httpCallback, Request.Method.DELETE, headers, params);
    }

    public static void uploadFiles(final String url, final RequestParams params, final AsyncHttpResponseHandler handler) {
        httpClient.post(url, params, handler);
    }
}
